﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CI.Models.Production;

namespace CI.Models
{
    public class JobModel : ModelBase, IDiagramModel
    {
        private List<object> _nodes = new List<object>();
        private List<Link> _links = new List<Link>();

        public JobModel()
        {
        }

        public void AddNode(object node)
        {
            InnerAddNode(node);
        }

        private object InnerAddNode(object node)
        {
            if (node is ICharacter)
            {
                _nodes.Add(node);
                OnNodeAdded(node);

                return node;
            }
            else if (node is ICorporation)
            {
                _nodes.Add(node);
                OnNodeAdded(node);

                return node;
            }
            else if (node is Activity)
            {
                var act = (Activity)node;

                if (act == Activity.BuyItems)
                {
                    var job = new BuyItemsJob();
                    _nodes.Add(job);
                    OnNodeAdded(job);
                    return job;
                }

                throw new NotImplementedException("Can't handle jobs for " + act);
            }
            else throw new NotImplementedException("Can't handle nodes of type " + node.GetType().Name);
        }

        public void AddNodeWithLink(object newNode, object linkedNode)
        {
            var added = InnerAddNode(newNode);

            if (added is IJob && linkedNode is IOwner)
            {
                var j = added as IJob;
                j.Owner = linkedNode as IOwner;
            }

            var link = new Link(added, linkedNode);
            OnLinkAdded(link);
        }

        public void RemoveNode(object node)
        {
            throw new NotImplementedException();
        }

        public event EventHandler<NodeEventArgs> NodeAdded;
        public event EventHandler<NodeEventArgs> NodeRemoved;
        public event EventHandler<LinkEventArgs> LinkAdded;
        public event EventHandler<LinkEventArgs> LinkRemoved;

        protected virtual void OnNodeAdded(object node)
        {
            var e = new NodeEventArgs(node);
            var eh = NodeAdded;
            if (eh != null) eh(this, e);
        }

        protected virtual void OnNodeRemoved(object node)
        {
            var e = new NodeEventArgs(node);
            var eh = NodeRemoved;
            if (eh != null) eh(this, e);
        }

        protected virtual void OnLinkAdded(Link link)
        {
            var e = new LinkEventArgs(link);
            var eh = LinkAdded;
            if (eh != null) eh(this, e);
        }

        protected virtual void OnLinkRemoved(Link link)
        {
            var e = new LinkEventArgs(link);
            var eh = LinkRemoved;
            if (eh != null) eh(this, e);
        }
    }

    public interface IDiagramModel
    {
        void AddNode(object node);
        void AddNodeWithLink(object newNode, object linkedNode);
        void RemoveNode(object node);

        event EventHandler<NodeEventArgs> NodeAdded;
        event EventHandler<NodeEventArgs> NodeRemoved;
        event EventHandler<LinkEventArgs> LinkAdded;
        event EventHandler<LinkEventArgs> LinkRemoved;
    }

    public class NodeEventArgs : EventArgs
    {
        public object Node { get; private set; }
        public NodeEventArgs(object node)
        {
            Node = node;
        }
    }

    public class LinkEventArgs : EventArgs
    {
        public Link Link { get; private set; }
        public LinkEventArgs(Link link)
        {
            Link = link;
        }
    }

    public class Link
    {
        public object FromNode { get; private set; }
        public object ToNode { get; private set; }
        public Link(object fromNode, object toNode)
        {
            FromNode = fromNode;
            ToNode = toNode;
        }
    }
}
